/**
 * GisController - part of PerlaGis Architecture
 *
 * Copyright (C) 2010 Ricardo Gonzalez (gomnaz@gmail.com)
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see http://www.gnu.org/licenses/
 */
package org.gis.services;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.gis.controllers.Sensor;
import org.gis.entities.SensorAction;
import org.gis.entities.Sensori;
import org.gis.exceptions.NoSuchSensorException;

/**
 * Classe che rappresenta i servizi di amministrazione del GisController.
 * Implementa i metodi necessari a creare o rimuovere sensori dal database e
 * a conoscere i sensori presenti nel database.
 *
 * @author Ricardo Gonzalez
 * @author Eva Gjeci
 */
@WebService()
public class Administration {

    @Resource
    private javax.transaction.UserTransaction utx;
    @PersistenceContext(unitName = "GisController")
    private EntityManager em;

    /**
     * Inserisce un nuovo sensore nel database avente come nome la stringa
     * passata come parametro.
     *
     * @param name il nome del sensore
     * @return la chiave del sensore
     * @return -1 se c'è stato un errore
     */
    @WebMethod(operationName = "addSensor")
    public int addSensor(@WebParam(name = "name") String name) {
        Sensori s = Sensor.newSensor(name);
        if (!saveSensor(s, SensorAction.ADD)) {
            return -1;

        }
        return s.getObjectid();
    }

    /**
     * Restituisce la lista dei sensore presenti nel database.
     *
     * @return la lista dei sensori
     */
    @WebMethod(operationName = "getSensorsList")
    public List<Sensori> getSensorsList() {
        return Sensor.getAll(em);
    }

    /**
     * Rimuove il sensore che corrisponde alla chiave passata come parametro.
     *
     * @param idSensore la chiave del sensore
     * @return true se l'operazione ha avuto successo
     * @throws NoSuchSensorException se non esiste un sensore associato alla chiave
     */
    @WebMethod(operationName = "removeSensor")
    public boolean removeSensor(@WebParam(name = "idSensore") int idSensore) throws NoSuchSensorException {
        Sensori s = Sensor.get(idSensore, em);
        if (!saveSensor(s, SensorAction.REMOVE)) {
            return false;

        }
        return true;
    }

    /**
     * Esegue le operazioni ADD e UPDATE sul database Gis relativamente
     * all'oggetto <code>Sensori</code> passato come parametro.
     *
     * @param object l'oggetto Sensori
     * @param action l'azione da compiere
     * @return true se ha avuto successo
     * @see SensorAction
     */
    private boolean saveSensor(Sensori object, SensorAction action) {
        boolean result = true;
        try {
            utx.begin();
            em.joinTransaction();
            if (action == SensorAction.ADD) {
                em.persist(object);
            } else if (action == SensorAction.REMOVE) {
                Sensori s0 = em.merge(object);
                em.remove(s0);
            } else if (action == SensorAction.UPDATE) {
                em.merge(object);
            }
            utx.commit();
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
            result = false;
            throw new RuntimeException(e);
        } finally {
            return result;
        }
    }
}
